using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;

namespace SuiHan.Commons.Logging {
    /// <summary>
    /// 清理日志的线程
    /// </summary>
    internal class LoggerCleanThread {
        /// <summary>
        /// 日志文件最多保留数量
        /// </summary>
        private const int Limit = 10;

        /// <summary>
        /// 间隔多少时间(ms)执行一次
        /// </summary>
        public int Interval { get; set; } = 1000 * 30;

        private readonly string fileFormat;
        private readonly string outputDir;

        /// <param name="fileFormat">日志文件名</param>
        /// <param name="outputDir">日志输出目录</param>
        public LoggerCleanThread(string fileFormat, string outputDir) {
            this.fileFormat = fileFormat;
            this.outputDir = outputDir;
        }

        public void Start() {
            new Thread(ClearLog) { Name = "log-clean-thread" }.Start();
        }

        private void ClearLog() {
            while (true) {
                try {
                    DirectoryInfo dir = new(outputDir);
                    if (dir.Exists is false) continue;

                    FileInfo[] logFiles = dir.GetFiles($"{fileFormat}-*.log", SearchOption.TopDirectoryOnly);
                    if (logFiles.Length >= Limit) {
                        List<FileInfo> fileList = logFiles.ToList();
                        // 按照文件最后写入时间升序排列
                        fileList.Sort((a, b) => {
                            long diff = a.LastWriteTime.Ticks - b.LastWriteTime.Ticks;
                            return diff < 0L ? -1 : diff > 0L ? 1 : 0;
                        });
                        // 保留写入时间靠后的文件, 删除时间早的
                        foreach (FileInfo fileInfo in fileList.Take(fileList.Count - Limit)) {
                            try {
                                fileInfo.Delete();
                            } catch (Exception e) {
                                Console.WriteLine("删除日志文件{0}发生异常: {1}", fileInfo.FullName, e);
                            }
                        }
                    }

                    Thread.Sleep(Interval);
                } catch (Exception e) {
                    Console.WriteLine("清理日志发生错误: {0}", e);
                }
            }
        }
    }
}
